bitkeeper revision 1.1159.33.1 (4120e700LNXbe5IhAOotAN5jyP0RJw)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Mon, 16 Aug 2004 16:55:28 +0000 (16:55 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Mon, 16 Aug 2004 16:55:28 +0000 (16:55 +0000)
suspend/resume fixes

linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h
tools/libxc/xc_linux_restore.c
tools/libxc/xc_linux_save.c
tools/libxc/xc_private.h
xen/common/dom_mem_ops.c

index 7a9cfed29ebfc93e409f0bb936892c41f0a5edcc..42f7830c876c9f6e50e46de34cfb16729c701cf5 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 #include <asm/io.h>
@@ -427,9 +428,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
          */
         if ( unlikely(rx->status <= 0) )
         {
-            /* Gate this error. We get a (valid) slew of them on suspend. */
-            if ( np->user_state == UST_OPEN )
-                printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
+           printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
             np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
             wmb();
             np->rx->req_prod++;
@@ -470,6 +469,15 @@ static int netif_poll(struct net_device *dev, int *pbudget)
         mcl->args[2] = 0;
         mcl++;
         (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
+
+#if 0 
+       if (unlikely(rx_mcl[0].args[5] != 0))
+           printk(KERN_ALERT"Hypercall0 failed %u\n",np->rx->resp_prod);
+
+       if (unlikely(rx_mcl[1].args[5] != 0))
+           printk(KERN_ALERT"Hypercall1 failed %u\n",np->rx->resp_prod);
+#endif
+
     }
 
     while ( (skb = __skb_dequeue(&rxq)) != NULL )
@@ -595,6 +603,7 @@ static void network_connect(struct net_device *dev,
 printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n",
        np->tx->req_prod,np->rx->req_prod);
 
+
     /* Step 3: All public and private state should now be sane.  Get
      * ready to start sending and receiving packets and give the driver
      * domain a kick because we've probably just requeued some
@@ -916,6 +925,8 @@ void netif_resume(void)
     struct net_private *np = NULL;
     int i;
 
+
+
 #if 1
     /* XXX THIS IS TEMPORARY */
 
@@ -932,6 +943,9 @@ void netif_resume(void)
 
            // stop bad things from happening until we're back up
            np->backend_state = BEST_DISCONNECTED;
+           
+           memset(np->tx,0,PAGE_SIZE);
+           memset(np->rx,0,PAGE_SIZE);
 
            cmsg.type      = CMSG_NETIF_FE;
            cmsg.subtype   = CMSG_NETIF_FE_INTERFACE_CONNECT;
index 5b89913a811ef52234b6c755d53525585e6711e2..611252cc840d24586ba2f57b20fa7e92cff3cd12 100644 (file)
@@ -374,7 +374,8 @@ static inline int HYPERVISOR_dom_mem_op(unsigned int   op,
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
-        "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order)
+        "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order),
+       "D" (DOMID_SELF)
         : "memory" );
 
     return ret;
index 0c1ca91ffc766597234e7631c59a3704ec84f081..513e838a38a93b817a4bbd96a3ea81a47c963c8d 100644 (file)
@@ -504,6 +504,54 @@ printf("XXXXXXXXXXXXXXX pin L2\n");
 
     xcio_info(ioctxt, "\b\b\b\b100%%\nMemory reloaded.\n");
 
+    /* Get the list of PFNs that are not in the psuedo-phys map */
+    {
+       unsigned int count, *pfntab;
+       int rc;
+       if ( xcio_read(ioctxt, &count, sizeof(count)) )
+       {
+           xcio_error(ioctxt, "Error when reading from state file");
+           goto out;
+       }
+
+       pfntab = malloc( sizeof(unsigned int) * count );
+       if ( !pfntab )
+       {
+           xcio_error(ioctxt, "Out of memory");
+           goto out;
+       }
+
+       if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) )
+       {
+           xcio_error(ioctxt, "Error when reading pfntab from state file");
+           goto out;
+       }
+
+       for(i=0;i<count;i++)
+       {
+           unsigned long pfn = pfntab[i];
+           pfntab[i]=pfn_to_mfn_table[pfn];
+           pfn_to_mfn_table[pfn] = 0x80000001;  // not in pmap
+       }
+
+       if ( count>0 )
+       {
+           if ( (rc = do_dom_mem_op( xc_handle,
+                                      MEMOP_decrease_reservation,
+                                      pfntab, count, 0, dom )) <0 )
+           {
+               xcio_error(ioctxt, "Could not decrease reservation : %d",rc);
+               goto out;
+           }
+           else
+           {
+               printf("Decreased reservation by %d pages\n", count);
+           }
+       }
+       
+    }
+
+
 
     if ( xcio_read(ioctxt, &ctxt,       sizeof(ctxt)) ||
          xcio_read(ioctxt, shared_info, PAGE_SIZE) )
index c3089955c9cee5fab033aef921154e9b98ed2ee2..5a47b30f5633bca8aac883585385d6d32677359d 100644 (file)
@@ -463,10 +463,6 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt)
            goto out;
        }
 
-       printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", 
-              op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
-              ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
-
     }
 
     /* calculate the power of 2 order of nr_pfns, e.g.
@@ -866,9 +862,41 @@ printf("type fail: page %i mfn %08lx\n",j,pfn_type[j]);
         goto out;
     }
 
-printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", 
-       op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame,
-       ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi );
+    /* Send through a list of all the PFNs that were not in map at the close */
+    {
+       unsigned int i,j;
+       unsigned int pfntab[1024];
+
+       for ( i = 0, j = 0; i < nr_pfns; i++ )
+       {
+           if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
+               j++;
+       }
+
+       if ( xcio_write(ioctxt, &j, sizeof(unsigned int)) )
+       {
+           xcio_error(ioctxt, "Error when writing to state file (6a)");
+           goto out;
+       }       
+
+       for ( i = 0, j = 0; i < nr_pfns; )
+       {
+           if ( live_pfn_to_mfn_table[i] >= 0x80000000UL )
+           {
+               pfntab[j++] = i;
+           }
+           i++;
+           if ( j == 1024 || i == nr_pfns )
+           {
+               if ( xcio_write(ioctxt, &pfntab, sizeof(unsigned long)*j) )
+               {
+                   xcio_error(ioctxt, "Error when writing to state file (6b)");
+                   goto out;
+               }       
+               j = 0;
+           }
+       }
+    }
 
     /* Map the suspend-record MFN to pin it. The page must be owned by 
        domid for this to succeed. */
index 3d0572501b819f0793c225f231674ee5d6400092..d70f7df58a1dd8ab60d1b362e26c7b340044d8fb 100644 (file)
@@ -127,6 +127,42 @@ static inline int do_multicall_op(int xc_handle,
  out1: return ret;
 }
 
+
+static inline int do_dom_mem_op(int            xc_handle,
+                               unsigned int   memop, 
+                               unsigned int *extent_list, 
+                               unsigned int  nr_extents,
+                               unsigned int   extent_order,
+                               domid_t        domid)
+{
+    privcmd_hypercall_t hypercall;
+    long ret = -EINVAL;
+       
+    hypercall.op     = __HYPERVISOR_dom_mem_op;
+    hypercall.arg[0] = (unsigned long)memop;
+    hypercall.arg[1] = (unsigned long)extent_list;
+    hypercall.arg[2] = (unsigned long)nr_extents;
+    hypercall.arg[3] = (unsigned long)extent_order;
+    hypercall.arg[4] = (unsigned long)domid;
+
+    if ( mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    {
+       fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
+                    " rebuild the user-space tool set?\n",ret,errno);
+        goto out2;
+    }
+
+ out2: (void)munlock(extent_list, nr_extents*sizeof(unsigned long));
+ out1: return ret;
+}    
+
+
 /*
  * PFN mapping.
  */
index e2a330ae96ca39be05197d169dfeedefb8630ef8..027dc790ce8088f8ce078679344d46ef87ef5564 100644 (file)
@@ -92,13 +92,32 @@ static long free_dom_mem(struct domain *d,
 long do_dom_mem_op(unsigned int   op, 
                    unsigned long *extent_list, 
                    unsigned long  nr_extents,
-                   unsigned int   extent_order)
+                   unsigned int   extent_order,
+                  domid_t        domid)
 {
-    if ( op == MEMOP_increase_reservation )
-        return alloc_dom_mem(current, extent_list, nr_extents, extent_order);
+    struct domain *d;
+    long rc = -ENOSYS;
 
-    if ( op == MEMOP_decrease_reservation )
-        return free_dom_mem(current, extent_list, nr_extents, extent_order);
+    if (domid == DOMID_SELF)
+       d = current;
+    else
+       d = find_domain_by_id(domid);
 
-    return -ENOSYS;
+    if (d==NULL)
+       return -ESRCH;
+
+    switch( op )
+    {
+    case MEMOP_increase_reservation:
+        rc = alloc_dom_mem(d, extent_list, nr_extents, extent_order);
+       break;
+    case MEMOP_decrease_reservation:
+        rc = free_dom_mem(d, extent_list, nr_extents, extent_order);
+       break;
+    }
+
+    if (domid!=DOMID_SELF)
+       put_domain(d);
+
+    return rc;
 }